<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html><head><title>Programming in Lua : 25</title>
<link rel="stylesheet" type="text/css" href="pil.css">
</head>
<body>
<p class="warning">
<A HREF="contents.html"><IMG TITLE="Programming in Lua (first edition)" SRC="capa.jpg" ALT="" ALIGN="left"></A>This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.<BR>The third edition targets Lua 5.2 and is available at <A HREF="http://www.amazon.com/exec/obidos/ASIN/859037985X/theprogrammil3-20">Amazon</A> and other bookstores.<BR>By buying the book, you also help to <A HREF="../donations.html">support the Lua project</A>.
</p>
<table width="100%" class="nav">
<tr>
<td width="10%" align="left"><a href="24.3.2.html"><img border="0" src="left.png" alt="Previous"></a></td>
<td width="80%" align="center"><a href="contents.html"><font face="Helvetica,Arial,sanserif">
<font color="gray">Programming in </font><font color="blue"> Lua</font>
</font></a></td>
<td width="10%" align="right"><a href="25.1.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
<tr>
<td width="10%" align="left"></td>
<td width="80%" align="center"><a href="contents.html#P4">Part IV. The C API</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="contents.html#25">Chapter 25. Extending your Application</a></td>
<td width="10%" align="right"></td></tr>
</table>
<hr/>
<h1>25 &ndash; Extending your Application</h1>

<p>

<p>An important use of Lua is as a <em>configuration</em> language.
In this chapter, we will illustrate how we can use Lua to
configure a program,
starting with a simple example and evolving
it to perform more complex tasks.

<p>As our first task,
let us imagine a simple configuration scenario:
Your C program (let us call it <code>pp</code>) has a window
and you want the user to be able to specify the
initial window size.
Clearly, for such simple tasks,
there are several options simpler than using Lua,
such as environment variables or files with name-value pairs.
But even using a simple text file,
you have to parse it somehow;
so, you decide to use a Lua configuration file
(that is, a plain text file that happens to be a Lua program).
In its simplest form,
this file can contain something like the next lines:
<pre>
    -- configuration file for program `pp'
    -- define window size
    width = 200
    height = 300
</pre>

<p>Now, you must use the Lua API to direct Lua to parse this file,
and then to get the values of the global variables <code>width</code>
and <code>height</code>.
The following function does the job:
<pre>
    #include &lt;lua.h>
    #include &lt;lauxlib.h>
    #include &lt;lualib.h>
    
    void load (char *filename, int *width, int *height) {
      lua_State *L = lua_open();
      luaopen_base(L);
      luaopen_io(L);
      luaopen_string(L);
      luaopen_math(L);
    
      if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0))
        error(L, "cannot run configuration file: %s",
                 lua_tostring(L, -1));
    
      lua_getglobal(L, "width");
      lua_getglobal(L, "height");
      if (!lua_isnumber(L, -2))
        error(L, "`width' should be a number\n");
      if (!lua_isnumber(L, -1))
        error(L, "`height' should be a number\n");
      *width = (int)lua_tonumber(L, -2);
      *height = (int)lua_tonumber(L, -1);
    
      lua_close(L);
    }
</pre>
First, it opens the Lua package and loads the standard libraries
(they are optional, but usually it is a good idea to have them around).
Then, it uses <code>luaL_loadfile</code> to load the chunk from file <code>filename</code>
and calls <code>lua_pcall</code> to run it.
In case of errors in any of these functions
(e.g., a syntax error in your configuration file),
the call returns a non-zero error code
and pushes the error message onto the stack.
As usual, our program uses <code>lua_tostring</code> with index <em>-1</em> to get
the message from the top of the stack.
(We defined the <code>error</code> function in <a href="24.1.html#first-ex">Section 24.1</a>.)

<p>After running the chunk,
the program needs to get the values of the
global variables.
For that,
it calls twice <code>lua_getglobal</code>,
whose single parameter (besides the omnipresent <code>lua_State</code>)
is the variable name.
Each call pushes the corresponding global value onto the top of the stack,
so that the width will be at index <em>-2</em>
and the height at index <em>-1</em> (at the top).
(Because the stack was previously empty,
you could also index from the bottom,
using <em>1</em> from the first value and <em>2</em> from the second.
By indexing from the top, however,
your code would work even if the stack
was not empty.)
Next, our example uses <code>lua_isnumber</code> to check whether
each value is numeric.
It then uses <code>lua_tonumber</code> to
convert such values to <code>double</code>
and C does the coercion to <code>int</code>.
Finally, it closes the Lua state and returns.

<p>Is it worth using Lua?
As I said before, for such simple tasks,
a simple file with only two numbers in it would be much
easier to use than Lua.
Even so, the use of Lua brings some advantages.
First, Lua handles all syntax details (and errors) for you;
your configuration file can even have comments!
Second, the user is already able to do more complex configurations
with it.
For instance,
the script may prompt the user for some information,
or it can query an environment variable
to choose a proper size:
<pre>
    -- configuration file for program `pp'
    if getenv("DISPLAY") == ":0.0" then
      width = 300; height = 300
    else
      width = 200; height = 200
    end
</pre>
Even in such simple configuration scenarios,
it is hard to anticipate what users will want;
but as long as the script defines the two variables,
your C application works without changes.

<p>A final reason for using Lua is that
now it is easy to add new
configuration facilities to your program;
this easiness creates an attitude
that results in programs that are more flexible.

<hr/>
<table width="100%" class="nav">
<tr valign="top">
<td width="90%" align="left">
<small>
  Copyright &copy; 2003&ndash;2004 Roberto Ierusalimschy.  All rights reserved.
</small>
</td>
<td width="10%" align="right"><a href="25.1.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
</table>


</body></html>

